/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * File Name          : freertos.c
 * Description        : Code for freertos applications
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2023 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "display.h"
#include "st7796_device.h"
#include "touch.h"
#include "lvgl.h"
#include "lv_port_disp_template.h"
#include "lv_port_indev_template.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
osThreadId_t DisplayTask_Handle;
const osThreadAttr_t DisplayTask_attributes = {
    .name = "displayTask",
    .stack_size = 1024 * 4,
    .priority = (osPriority_t)osPriorityNormal1,
};
/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
    .name = "defaultTask",
    .stack_size = 128 * 4,
    .priority = (osPriority_t)osPriorityNormal,
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
void DisplayTask(void *argument);
/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/**
 * @brief  FreeRTOS initialization
 * @param  None
 * @retval None
 */
void MX_FREERTOS_Init(void)
{
    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* USER CODE BEGIN RTOS_MUTEX */
    /* add mutexes, ... */
    /* USER CODE END RTOS_MUTEX */

    /* USER CODE BEGIN RTOS_SEMAPHORES */
    /* add semaphores, ... */
    /* USER CODE END RTOS_SEMAPHORES */

    /* USER CODE BEGIN RTOS_TIMERS */
    /* start timers, add new ones, ... */
    /* USER CODE END RTOS_TIMERS */

    /* USER CODE BEGIN RTOS_QUEUES */
    /* add queues, ... */
    /* USER CODE END RTOS_QUEUES */

    /* Create the thread(s) */
    /* creation of defaultTask */
    defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

    /* USER CODE BEGIN RTOS_THREADS */
    DisplayTask_Handle = osThreadNew(DisplayTask, NULL, &DisplayTask_attributes);
    /* USER CODE END RTOS_THREADS */

    /* USER CODE BEGIN RTOS_EVENTS */
    /* add events, ... */
    /* USER CODE END RTOS_EVENTS */
}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
 * @brief  Function implementing the defaultTask thread.
 * @param  argument: Not used
 * @retval None
 */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
    /* USER CODE BEGIN StartDefaultTask */
    printf("TFT test. \r\n");
    /* Infinite loop */
    for (;;)
    {
        HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
        osDelay(500);
    }
    /* USER CODE END StartDefaultTask */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

void lv_ex_label_1(void)
{
    lv_obj_t *label2 = lv_label_create(lv_scr_act());
    lv_label_set_recolor(label2, true);
    lv_label_set_long_mode(label2, LV_LABEL_LONG_SCROLL_CIRCULAR); /*Circular scroll*/
    lv_obj_set_width(label2, 120);
    // Hello world ! Trisuborn.
    lv_label_set_text(label2, "#ff0000 Hello# #00ff00 world ! Trisuborn.#");
    lv_obj_align(label2, LV_ALIGN_TOP_LEFT, 0, 0);
}

void lv_ex_switch_1(void)
{
    lv_obj_t *switch_obj = lv_switch_create(lv_scr_act());
    // lv_obj_set_style_bg_color(switch_obj, lv_color_hex(0xdf5345), LV_PART_MAIN);    // 设置颜色
    lv_obj_add_state(switch_obj, LV_STATE_CHECKED);   // 设置开关状态
    lv_obj_clear_state(switch_obj, LV_STATE_CHECKED); // 清除开关状态
    lv_obj_set_size(switch_obj, 120, 60);
    lv_obj_align(switch_obj, LV_ALIGN_CENTER, 0, 0);
}

uint8_t DebugKey = 0;
lv_obj_t *switch_obj;

void switch_obj_cb(lv_event_t *eventTemp)
{
    lv_event_code_t code = lv_event_get_code(eventTemp);

    if (code == LV_EVENT_VALUE_CHANGED)
    {
        if (lv_obj_has_state(switch_obj, LV_STATE_CHECKED))
        {
            printf("LED NO \r\n");
        }
        else
        {
            printf("LED OFF \r\n");
        }
    }
}
#if 1
void DisplayTask(void *argument)
{
    osDelay(100);
    lv_init();
    lv_port_disp_init();
    lv_port_indev_init();
    printf("lvgl init. \r\n");

    lv_ex_label_1();
    switch_obj = lv_switch_create(lv_scr_act());
    // lv_obj_set_style_bg_color(switch_obj, lv_color_hex(0xdf5345), LV_PART_MAIN);    // 设置颜色
    // lv_obj_add_state(switch_obj, LV_STATE_CHECKED);     // 设置开关状态
    // lv_obj_clear_state(switch_obj, LV_STATE_CHECKED);   // 清除开关状态
    lv_obj_set_size(switch_obj, 120, 60);
    lv_obj_align(switch_obj, LV_ALIGN_CENTER, 0, 0);
    lv_obj_add_event_cb(switch_obj, switch_obj_cb, LV_EVENT_VALUE_CHANGED, NULL);

    printf("lvgl begin. \r\n");
    for (;;)
    {
        lv_task_handler();
        osDelay(5);

        if (DebugKey == 1)
        {
            DebugKey = 0;
            lv_obj_add_state(switch_obj, LV_STATE_CHECKED);
        }
        else if (DebugKey == 2)
        {
            DebugKey = 0;
            lv_obj_clear_state(switch_obj, LV_STATE_CHECKED);
        }
    }
}
#else /* Display Test */
void DisplayTask(void *argument)
{
    osDelay(100);
    ST7796S_LcdInit();
    osDelay(1000);
    LCD_Clear(0);
    osDelay(1000);
    LCD_Clear(0x00ff);
    osDelay(1000);
    LCD_Clear(0x00);
    LCD_DrawString(0, 0, "Hello World!", LCD_GREEN);
    LCD_DrawString(1, 1, "Temp: 255", LCD_WHITE);
    LCD_DrawString(2, 2, "DIY", LCD_RED);

    for (;;)
    {
        osDelay(5);
    }
}
#endif
/* USER CODE END Application */
